<?php


namespace App\Services;


use App\Models\Config;
use App\Models\SubAccount;
use App\Models\User;
use App\Utils\Code;
use App\Utils\Regex;
use App\Utils\Sms;

class SmsService extends BaseService
{

    /**
     * 发送验证码
     * @param array $params
     * @return User|bool|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \AlibabaCloud\Client\Exception\ClientException|\Exception
     */
    public function captcha(array $params) {
        if (!isset($params['mode'])) {
            throw new \Exception('验证码发送模式不能为空', Code::PARAMETER_ERROR);
        } elseif (!is_numeric($params['mode']) || !in_array($params['mode'], [1,2,3,4,5])) {
            throw new \Exception('请设置正确的验证码发送模式', Code::PARAMETER_ERROR);
        }
        if ($params['mode'] == 5) {
            $uniqid = md5(uniqid(microtime(true),true));
            \Cache::put("login_qr_code_{$uniqid}", date('Y-m-d H:i:s'), 60 * 5);
            return $uniqid;
        } else {
            if (!isset($params['phone'])) {
                throw new \Exception('接收手机号码不能为空', Code::PARAMETER_ERROR);
            } elseif (!Regex::check('phone', $params['phone'])) {
                throw new \Exception('手机号码格式不正确', Code::PARAMETER_ERROR);
            }
            $userInfo = User::where('phone', $params['phone'])->first();
            if (in_array($params['mode'], [1,4]) && !$userInfo) {
                throw new \Exception('该手机号码还未注册', Code::PARAMETER_ERROR);
            } elseif ($params['mode'] == 2 && $userInfo) {
                throw new \Exception('该手机号码已经注册', Code::PARAMETER_ERROR);
            }
            $captcha = \Cache::get("captcha_{$params['phone']}", null);
            if (config('app.env') != 'production') {
                $captcha = '123456';
            } else {
                if (!$captcha || $captcha == '123456') {
                    $captcha = mt_rand(1,9) . str_pad(random_int(1000, 99999), 5, 0, STR_PAD_LEFT);
                }
                // 发送验证码短信
                $smsInfo = Config::where('type', 0)->where('key', 'sms')->first();
                if (!isset($smsInfo->params['tpl']['captcha']) || !$smsInfo->params['tpl']['captcha']) {
                    throw new \Exception('系统短信通道未配置', Code::LACK_OF_CONDITIONS);
                }
                $response = (new Sms($smsInfo->value, $smsInfo->params['access_ak'], $smsInfo->params['access_sk'], $smsInfo->params['signature'], $smsInfo->params['appid']))
                    ->captcha($params['phone'], $captcha, $smsInfo->params['tpl']['captcha']);
                $response = json_decode($response, true);
                if (isset($response['SendStatusSet'][0]['Message']) && $response['SendStatusSet'][0]['Message'] != 'send success') {
                    throw new \Exception($response['SendStatusSet'][0]['Message'], Code::REMOTE_SERVER);
                }
            }
            \Cache::put("captcha_{$params['phone']}", $captcha, 60 * 5);
            return $params['mode'] == 4 ? $userInfo : true;
        }
    }

    /**
     * 校对短信验证码
     * @param $phone
     * @param $captcha
     * @param bool $delCache
     * @return bool
     * @throws \Exception
     */
    public function checkCaptcha($phone, $captcha, $delCache = true){
        $code = \Cache::get("captcha_{$phone}", null);
        if (!$code){
            throw new \Exception('验证码已失效，请重新获取', Code::PARAMETER_ERROR);
        } elseif (!hash_equals(strval($code), strval($captcha))){
            throw new \Exception('验证码不正确', Code::PARAMETER_ERROR);
        }
        // 删除验证码
        if ($delCache && config('app.env') != 'local'){
            \Cache::forget("captcha_{$phone}");
        }
        return true;
    }
}
